﻿using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using CustomControls;
using DataAccess;
using Model;
using Model.EntityModel;
using Actor = Model.EntityModel.Actor;
using Person = Model.EntityModel.Person;

namespace Project
{
    /// <summary>
    /// Interaction logic for ModifyDeclarationContent.xaml
    /// </summary>
    public partial class ModifyDeclarationContent : UserControl
    {
        private Declaration declaration;
        private long ComplaintId;
        private List<ShowableQuestion> DeclarationQuestions; 
        private bool isEnabledPersonalInfo;
        private Person Victim;
        private Person Complainant;
        private Person Informer;
        private Person Aggressor;
        private Person Witness;

        public ModifyDeclarationContent(long complaintId, List<ShowableQuestion> declarationQuestions)
        {
            ComplaintId = complaintId;
            DeclarationQuestions = declarationQuestions;
            InitializeComponent();
            listBoxQuestions.DataContext = DeclarationQuestions;
            cboxActorCountry.ItemsSource = GetCountryList();
            DisablePersonalInfo();
            FillFields();
            tbActorAddress.DeactivateBlankValidation();
            tbActorZone.DeactivateBlankValidation();
            tbActorPhone.DeactivateBlankValidation();
            tbActorPhone.AddValitationRule(new PhoneValidationRule());
            declaration =
                DeclarationDataAccess.GetDeclarationsById(declarationQuestions.FirstOrDefault().DeclarationId);
            lblCurrentTime.Content = declaration.RegistrationDate.ToShortTimeString();
            lblTodayDate.Content = declaration.RegistrationDate.ToShortDateString();
            lblRegistrationDate.Content = lblTodayDate.Content;
            Informer = new Person();
            Witness = new Person();
            Informer.Nationality = "Bolivia";
            Witness.Nationality = "Bolivia";
            tbQuestion.AddValitationRule(new LenghtValidationRule(15));
            tbResponse.AddValitationRule(new LenghtValidationRule(15));
            gridAddQuestion.Height = 0;
            SetPersonalInfo();
        }

        private void SetPersonalInfo()
        {
            var actorInfo = DeclarationDataAccess.GetDeclarationsById(DeclarationQuestions.FirstOrDefault().DeclarationId).Actor;
            if(actorInfo.Type=="Informador")
            {
                Informer = actorInfo.Person;
                rbtnInformer.IsChecked = true;
            }
            else if(actorInfo.Type=="Testigo")
            {
                Witness = actorInfo.Person;
                rbtnWitness.IsChecked = true;
            }
            else if (actorInfo.Type == "Victima")
            {
                rbtnVictim.IsChecked = true;
            }
            else if (actorInfo.Type == "Agresor")
            {
                rbtnAggressor.IsChecked = true;
            }
            else if (actorInfo.Type == "Denunciante")
            {
                rbtnComplainant.IsChecked = true;
            }
        }

        public void FillFields()
        {
            lblCaseNumber.Content = ComplaintId;
            lblCaseNum.Content = ComplaintId;
            Victim = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Victima", ComplaintId).Person;
            Aggressor = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Agresor", ComplaintId).Person;
            Complainant = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Denunciante", ComplaintId).Person;
            lblAggressor.Content = Aggressor.Name + " " + Aggressor.PaternalName + " " + Aggressor.MaternalName;
         }

        private List<string> GetCountryList()
        {
            List<string> cultureList = new List<string>();
            CultureInfo[] cultures = CultureInfo.GetCultures(CultureTypes.AllCultures);
            foreach (CultureInfo culture in cultures)
            {
                if (!culture.IsNeutralCulture && culture.LCID != 0x7F)
                {
                    RegionInfo region = new RegionInfo(culture.LCID);
                    if (!(cultureList.Contains(region.DisplayName)))
                        cultureList.Add(region.DisplayName);
                }
            }
            var sortedList = (from culture in cultureList
                              orderby culture
                              select culture).ToList();
            return sortedList;
        }

        public void DisablePersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if(!(control is Label))
                    (control as Control).IsEnabled = false;
            }
            isEnabledPersonalInfo = false;
        }

        public void EnablePersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if (!(control is Label))
                 
                    (control as Control).IsEnabled = true;
            }
            isEnabledPersonalInfo = true;
            tbActorCI.IsEnabled = false;
        }

        public void SetReadOnlyPersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if(control is MaskTextBox)
                    (control as MaskTextBox).IsReadOnly = true;
                if (control is ValidationComboBox)
                    (control as ValidationComboBox).IsHitTestVisible = false;
                if (control is ComboBox)
                    (control as ComboBox).IsHitTestVisible = false;
            }
            tbActorWorkPlace.IsReadOnly = false;
        }

        public void UnSetReadOnlyPersonalInfo()
        {
            foreach (var control in PersonalInfo.Children)
            {
                if (control is MaskTextBox)
                    (control as MaskTextBox).IsReadOnly = false;
                if (control is ValidationComboBox)
                    (control as ValidationComboBox).IsHitTestVisible = true;
                if (control is ComboBox)
                    (control as ComboBox).IsHitTestVisible = true;
            }
        }

        public void SetPersonalInfoContext(Person person)
        {
            if (person != null)
            {
                tbActorName.Text = person.Name;
                tbActorLastName.Text = person.PaternalName;
                tbActorMiddleName.Text = person.MaternalName;
                tbActorCI.Text = person.CiPassport == 0 ? "" : person.CiPassport.ToString();
                tbActorAddress.Text = person.Address;
                tbActorPhone.Text = person.Phone;
                tbActorZone.Text = person.Zone;
                tbActorWorkPlace.Text = person.WorkPlace;
                cboxActorCountry.SelectedValue = person.Nationality;
                cbActorCivilStatus.SelectedValue = person.CivilStatus;
            }
        }

        private void rbtnVictim_Checked(object sender, RoutedEventArgs e)
        {
            if(!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Victim);
            SetReadOnlyPersonalInfo();
            tbActorCI.IsEnabled = true;
            btnUnlockCi.Visibility = Visibility.Collapsed;
        }

        private void rbtnComplainant_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Complainant);
            SetReadOnlyPersonalInfo();
            tbActorCI.IsEnabled = true;
            btnUnlockCi.Visibility = Visibility.Collapsed;
        }

        private void rbtnInformer_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Informer);
            UnSetReadOnlyPersonalInfo();
            tbActorCI.IsEnabled = false;
            btnUnlockCi.Visibility = Visibility.Visible;
        }

        private void rbtnAggressor_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Aggressor);
            SetReadOnlyPersonalInfo();
            tbActorCI.IsEnabled = true;
            btnUnlockCi.Visibility = Visibility.Collapsed;

        }

        private void rbtnWitness_Checked(object sender, RoutedEventArgs e)
        {
            if (!isEnabledPersonalInfo)
                EnablePersonalInfo();
            lblSelError.Content = "";
            SetPersonalInfoContext(Witness);
            UnSetReadOnlyPersonalInfo();
            tbActorCI.IsEnabled = false;
            btnUnlockCi.Visibility = Visibility.Visible;
        }

        private void btnRegister_Click(object sender, RoutedEventArgs e)
        {
            bool res = CheckHasErrors();
            try
            {
                if (!res)
                {
                    long actorId=0;
                    if ((bool)rbtnVictim.IsChecked)
                    {
                        var actr = (from a in Victim.Actor
                                    where a.IdComplaint == ComplaintId
                                    select a).SingleOrDefault();
                        actorId = actr.Id;
                        actr.Person.WorkPlace = tbActorWorkPlace.Text;
                        PersonAndActorDataAccess.UpdatePerson(actr.Person.CiPassport, actr.Person);
                    }
                    if ((bool)rbtnComplainant.IsChecked)
                    {
                        var actr = (from a in Complainant.Actor
                                    where a.IdComplaint == ComplaintId
                                    select a).SingleOrDefault();
                        actorId = actr.Id;
                        actr.Person.WorkPlace = tbActorWorkPlace.Text;
                        PersonAndActorDataAccess.UpdatePerson(actr.Person.CiPassport, actr.Person);
                    }
                    if ((bool)rbtnInformer.IsChecked)
                    {
                        bool exists = PersonAndActorDataAccess.GetPersonByCi(long.Parse(tbActorCI.Text))!=null;
                            var pers = new Person();
                            pers.Id = tbActorCI.Text + DateTime.Now.Date.ToString(
                    CultureInfo.GetCultureInfo("es-ES").DateTimeFormat.ShortDatePattern);
                            pers.Name = tbActorName.Text;
                            pers.PaternalName = tbActorLastName.Text;
                            pers.MaternalName = tbActorMiddleName.Text;
                            pers.CiPassport = long.Parse(tbActorCI.Text);
                            pers.Address = tbActorAddress.Text;
                            pers.Phone = tbActorPhone.Text;
                            pers.Zone = tbActorZone.Text;
                            pers.WorkPlace = tbActorWorkPlace.Text;
                            pers.Nationality = cboxActorCountry.SelectedValue.ToString();
                            pers.CivilStatus = cbActorCivilStatus.SelectedValue.ToString();
                            pers.RegisterDate = DateTime.Now;
                        Informer = pers;
                        if(!exists)
                            Informer = PersonAndActorDataAccess.InsertPerson(pers);
                        if(exists)
                        {
                            var tempInformer = PersonAndActorDataAccess.GetPersonByCi(long.Parse(tbActorCI.Text));
                            Informer.Id = tempInformer.Id;
                            PersonAndActorDataAccess.UpdatePerson(Informer.CiPassport, Informer);
                        }
                        var actor = new Actor();
                        bool actorExists = PersonAndActorDataAccess.ActorAlreadyExists(Informer.Id, ComplaintId,
                                                                                       "Informador");
                        if (!actorExists)
                        {
                            actor =
                                PersonAndActorDataAccess.InsertActor(new Actor
                                                                         {
                                                                             IdPerson = Informer.Id,
                                                                             IdComplaint = ComplaintId,
                                                                             Type = "Informador"
                                                                         });
                        }
                        else
                        {
                            actor = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Informador", ComplaintId, Informer.Id);
                        }
                        actorId = actor.Id;
                    }
                    if ((bool)rbtnWitness.IsChecked)
                    {
                        bool exists = PersonAndActorDataAccess.GetPersonByCi(long.Parse(tbActorCI.Text))!=null;
                            var pers = new Person();
                            pers.Id = tbActorCI.Text + DateTime.Now.Date.ToString(
                    CultureInfo.GetCultureInfo("es-ES").DateTimeFormat.ShortDatePattern);
                            pers.Name = tbActorName.Text;
                            pers.PaternalName = tbActorLastName.Text;
                            pers.MaternalName = tbActorMiddleName.Text;
                            pers.CiPassport = long.Parse(tbActorCI.Text);
                            pers.Address = tbActorAddress.Text;
                            pers.Phone = tbActorPhone.Text;
                            pers.Zone = tbActorZone.Text;
                            pers.WorkPlace = tbActorWorkPlace.Text;
                            pers.Nationality = cboxActorCountry.SelectedValue.ToString();
                            pers.CivilStatus = cbActorCivilStatus.SelectedValue.ToString();
                            pers.RegisterDate = DateTime.Now;
                        Witness = pers;
                        if(!exists)
                            Witness = PersonAndActorDataAccess.InsertPerson(pers);
                        if (exists)
                        {
                            var tempWitness = PersonAndActorDataAccess.GetPersonByCi(long.Parse(tbActorCI.Text));
                            Witness.Id = tempWitness.Id;
                            PersonAndActorDataAccess.UpdatePerson(Witness.CiPassport, Witness);
                        }
                        var actor = new Actor();
                        bool actorExists = PersonAndActorDataAccess.ActorAlreadyExists(Witness.Id, ComplaintId,
                                                                                       "Testigo");
                        if (!actorExists)
                        {
                            actor =
                                PersonAndActorDataAccess.InsertActor(new Actor
                                                                         {
                                                                             IdPerson = Witness.Id,
                                                                             IdComplaint = ComplaintId,
                                                                             Type = "Testigo"
                                                                         });
                        }
                        else
                        {
                            actor = PersonAndActorDataAccess.GetActorByTypeAndComplaintId("Testigo", ComplaintId, Witness.Id);
                        }

                        actorId = actor.Id;
                    }
                    if ((bool)rbtnAggressor.IsChecked)
                    {
                        var actr = (from a in Aggressor.Actor
                                    where a.IdComplaint == ComplaintId
                                    select a).SingleOrDefault();
                        actorId = actr.Id;
                        actr.Person.WorkPlace = tbActorWorkPlace.Text;
                        PersonAndActorDataAccess.UpdatePerson(actr.Person.CiPassport, actr.Person);
                    }

                    foreach (var lbItem in listBoxQuestions.Items)
                    {
                        if (lbItem is ShowableQuestion)
                        {
                            var declarationQuestion = lbItem as ShowableQuestion;
                            DeclarationDataAccess.UpdateDeclaration(new Declaration
                                                                        {
                                                                            Id = declarationQuestion.DeclarationId,
                                                                            RegistrationDate = declaration.RegistrationDate,
                                                                            ActorId = actorId,
                                                                            ComplaintId = ComplaintId,
                                                                            Question = declarationQuestion.Question,
                                                                            Answer = declarationQuestion.Answer,
                                                                            Status = false
                                                                        });
                        }
                    }

                    var style = new Style(typeof(Xceed.Wpf.Toolkit.MessageBox));
                    style.Setters.Add(new Setter(Xceed.Wpf.Toolkit.MessageBox.YesButtonContentProperty, "Si"));
                    var resB = Xceed.Wpf.Toolkit.MessageBox.Show("Se modificó la declaración exitosamente, Desea imprimir la declaración?",
                                                                "Exito!", MessageBoxButton.YesNo,
                                                                MessageBoxImage.Information, style);
                    if (resB == MessageBoxResult.Yes)
                    {
                        var declarations = DeclarationDataAccess.GetAllShowableDeclarations(ComplaintId);
                        foreach (var showableDeclaration in declarations)
                        {
                            if (showableDeclaration.RegistrationDate == lblRegistrationDate.Content.ToString() && showableDeclaration.DeclarantCI.ToString() == tbActorCI.Text)
                            {
                                var items = new ObservableCollection<UserControl>();
                                items.Add(new PrintDeclaration(ComplaintId, showableDeclaration.QuestionsAndAnswer));
                                var a = new PrintPreviewDialogV2(items);
                                a.ShowDialog();
                                break;
                            }
                        }

                    }
                    else
                    {
                        Xceed.Wpf.Toolkit.MessageBox.Show("Puede imprimir la declaración posteriormente, entrando a Ver Denuncias, click sobre la denuncia: Ver Declaraciones, y selecciona Ver Declaración",
                                                                "Información!", MessageBoxButton.OK, MessageBoxImage.Information);
                    }
                    UIWindowManager.CleanWindow(this);
                }
                else
                {
                    Xceed.Wpf.Toolkit.MessageBox.Show("Debe llenar todos los campos para poder continuar", "Error!");
                }
            }
            catch (Exception h)
            {
                Xceed.Wpf.Toolkit.MessageBox.Show("Ocurrió un error inesperado mientras se trataba de registrar la declaración", "Error!");
            }
        }
        
        private bool CheckHasErrors()
        {
            bool res = false;
            foreach (var ctrl in PersonalInfo.Children)
            {
                if (ctrl is MaskTextBox)
                {
                    (ctrl as MaskTextBox).GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
                    if (Validation.GetHasError(ctrl as MaskTextBox) && (ctrl as MaskTextBox).Name != "tbQuestion" && (ctrl as MaskTextBox).Name != "tbResponse")
                        res = true;
                }
                if (ctrl is ValidationComboBox)
                {
                    (ctrl as ValidationComboBox).LostFocusEventHandler(ctrl as ValidationComboBox, null);
                    if (Validation.GetHasError(ctrl as ValidationComboBox))
                        res = true;
                }
            }
            if (!isEnabledPersonalInfo)
            {
                lblSelError.Content = "Debe seleccionar un declarante para poder registrar una declaración";
                res = true;
            }
            if (listBoxQuestions.Items.Count <= 0)
            {
                lblNoQuestionsError.Visibility = Visibility.Visible;
                res = true;
            }
            return res;
        }


        private void ShowDialogGrid()
        {
            tbQuestion.IsHitTestVisible = true;
            tbResponse.IsHitTestVisible = true;
            DoubleAnimation doubleAnimation = new DoubleAnimation(0, 238, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
            Storyboard st = new Storyboard();
            st.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(st, new PropertyPath("Height"));
            Storyboard.SetTargetName(st, "gridAddQuestion");
            BeginStoryboard(st);
        }

        private void HideDialogGrid()
        {
            tbQuestion.IsHitTestVisible = false;
            tbResponse.IsHitTestVisible = false;
            DoubleAnimation doubleAnimation = new DoubleAnimation(238, 0, new Duration(new TimeSpan(0, 0, 0, 0, 500)));
            Storyboard st = new Storyboard();
            st.Children.Add(doubleAnimation);
            Storyboard.SetTargetProperty(st, new PropertyPath("Height"));
            Storyboard.SetTargetName(st, "gridAddQuestion");
            BeginStoryboard(st);
        }

        private void btnAddCancel_Click(object sender, RoutedEventArgs e)
        {
            HideDialogGrid();
            Validation.ClearInvalid(tbQuestion.GetBindingExpression(MaskTextBox.TextProperty));
            Validation.ClearInvalid(tbResponse.GetBindingExpression(MaskTextBox.TextProperty));
            if (tbQuestion.Text.Length >= 15 && tbResponse.Text.Length >= 15)
                lblQuestionERROR.Visibility = Visibility.Hidden;
            tbResponse.IsEnabled = true;
        }

        private void btnAddSuccess_Click(object sender, RoutedEventArgs e)
        {
            tbQuestion.GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
            bool hasError = Validation.GetHasError(tbQuestion) || Validation.GetHasError(tbResponse);
            if (!hasError)
            {
                foreach (var declarationQuestion in DeclarationQuestions)
                {
                    if (declarationQuestion.NumberOfQuestion.ToString() == lblQuestionNumber.Content.ToString())
                    {
                        declarationQuestion.Answer = tbResponse.Text;
                        declarationQuestion.Question = tbQuestion.Text;
                    }
                }
                listBoxQuestions.Items.Refresh();
                listBoxQuestions.UpdateLayout();
                HideDialogGrid();
                tbQuestion.Text = "";
                tbResponse.Text = "";
                Validation.ClearInvalid(tbQuestion.GetBindingExpression(MaskTextBox.TextProperty));
                Validation.ClearInvalid(tbResponse.GetBindingExpression(MaskTextBox.TextProperty));
                lblQuestionERROR.Visibility = Visibility.Hidden;
                lblNoQuestionsError.Visibility = Visibility.Hidden;
                tbResponse.IsEnabled = false;
            }
            else
            {
                lblQuestionERROR.Visibility = Visibility.Visible;
            }
        }


        private void btnEdit_Click(object sender, RoutedEventArgs e)
        {
            if (string.IsNullOrEmpty(tbQuestion.Text) && string.IsNullOrEmpty(tbResponse.Text))
                lblQuestionERROR.Visibility = Visibility.Hidden;
                Button cmd = (Button)sender;
                if (cmd.DataContext is ShowableQuestion)
                {
                    ShowableQuestion questionToEdit = (ShowableQuestion)cmd.DataContext;
                    tbQuestion.Text = questionToEdit.Question;
                    tbResponse.Text = questionToEdit.Answer;
                    lblQuestionNumber.Content = questionToEdit.NumberOfQuestion;
                }
                tbQuestion.GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
                tbResponse.GetBindingExpression(MaskTextBox.TextProperty).UpdateSource();
                if (tbQuestion.Text.Length >= 15 && tbResponse.Text.Length >= 15)
                    lblQuestionERROR.Visibility = Visibility.Hidden;
                else
                {
                    lblQuestionERROR.Visibility = Visibility.Visible;
                }
                ShowDialogGrid();
        }

        private void BtnUnlockAnswer_OnClick(object sender, RoutedEventArgs e)
        {
            var grantPermission = new GrantDirectorPermissionWindows();
            if (grantPermission.ShowDialog() == true)
            {
                tbResponse.IsEnabled = true;
            }
        }

        private void BtnUnlockCi_OnClick(object sender, RoutedEventArgs e)
        {
            var grantPermission = new GrantDirectorPermissionWindows();
            if (grantPermission.ShowDialog() == true)
            {
                tbActorCI.IsEnabled = true;
            }
        }

        private void BtnKeyCompCi_OnClick(object sender, RoutedEventArgs e)
        {
            var grantPermission = new GrantDirectorPermissionWindows();
            if (grantPermission.ShowDialog() == true)
            {
                rbtnVictim.IsHitTestVisible = true;
                rbtnComplainant.IsHitTestVisible = true;
                rbtnAggressor.IsHitTestVisible = true;
                rbtnInformer.IsHitTestVisible = true;
                rbtnWitness.IsHitTestVisible = true;
            }
        }
    }
}
